﻿using Stateless;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using TravelServer.DTOs;

namespace TravelServer.Models
{
    public enum OrderStateEnum
    {
        Pending,//订单已生成
        Processing,//支付处理中
        Completed,//支付完成
        Declined,//交易失败
        Cancelled,//交易取消
        Refund//已退款

    }

    public enum OrderStateTriggerEnum
    {
        PlaceOrder,//支付
        Approve,//支付成功
        Reject,//支付失败
        Cancle,//支付取消
        Return//退货退款
    }
    public class Order
    {
        public Order()
        {
            InitStateMachine();
        }
        [Key]
        public Guid Id { get; set; }

        [ForeignKey("UserId")]
        public string? UserId {  get; set; }
        public AppUser? User { get; set; }

        public ICollection<LineItem>? OrderLineItems { get; set; }

        public OrderStateEnum State { get; set; }

        //数据库时间一般是UTC
        public DateTime CreateDataUTC { get; set; }

        //第三方支付数据，由第三方支付回调给我们，直接保存到数据库中。
        //前端获取是，直接返回json 字符串，由前端根据具体支付反序列化
        public string? TransactionMetadata {  get; set; }

        StateMachine<OrderStateEnum, OrderStateTriggerEnum> machine;

        void InitStateMachine()
        {
            machine=new StateMachine<OrderStateEnum, OrderStateTriggerEnum>(OrderStateEnum.Pending);
           //由Pending 触发 :支付处理中  支付取消
            machine.Configure(OrderStateEnum.Pending)
                .Permit(OrderStateTriggerEnum.PlaceOrder, OrderStateEnum.Processing)
                .Permit(OrderStateTriggerEnum.Cancle, OrderStateEnum.Cancelled);
            //由Processing 触发:支付完成 支付失败
            machine.Configure(OrderStateEnum.Processing)
                .Permit(OrderStateTriggerEnum.Approve,OrderStateEnum.Completed)
                .Permit(OrderStateTriggerEnum.Reject,OrderStateEnum.Declined);
            //支付失败  触发：重新支付
            machine.Configure(OrderStateEnum.Declined)
                .Permit(OrderStateTriggerEnum.PlaceOrder, OrderStateEnum.Processing);
            //支付完成  触发：退款
            machine.Configure(OrderStateEnum.Completed)
                .Permit(OrderStateTriggerEnum.Return, OrderStateEnum.Refund);
        }

    }
}
